package com.wjy.icu.service.impl;

import cn.hutool.core.util.HexUtil;
import com.wjy.icu.common.exception.BusinessException;
import com.wjy.icu.common.exception.MqttException;
import com.wjy.icu.common.utils.StringUtils;
import com.wjy.icu.domain.*;
import com.wjy.icu.domain.vo.EquitmentVo;
import com.wjy.icu.domain.vo.UpData;
import com.wjy.icu.emqx.client.MqttPushClient;
import com.wjy.icu.emqx.utils.MqttUtils;
import com.wjy.icu.mapper.*;
import com.wjy.icu.service.IMqttService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description:
 * @author: wangjunyong
 * @date: 2021/10/19 10:23
 */
@Slf4j
@Service
public class MqttServiceImpl implements IMqttService {

    @Resource
    EquipmentMapper equipmentMapper;
    @Resource
    EquipmentFuncMapper equipmentFuncMapper;
    @Autowired
    private MqttPushClient mqttPushClient;
    @Resource
    RegulateModeMapper regulateModeMapper;
    @Resource
    EquipmentUserLevelMapper equipmentUserLevelMapper;
    @Resource
    PresetModelsConditionMapper presetModelsConditionMapper;

    @Override
    public void initialize(EquitmentVo equitmentVo) {
        EquipmentExample example = new EquipmentExample();
        example.createCriteria().andMacEqualTo(equitmentVo.getMac());
        List<Equipment> equipments = equipmentMapper.selectByExample(example);
        Integer equipmentId=0;
        if (equipments.size()>0){
            Equipment equipment = equipments.get(0);
            equipment.setStatus(9);
            equipment.setUserId(equitmentVo.getUserId());
            equipment.setActiveDate(LocalDateTime.now());
            equipment.setGmtModify(LocalDateTime.now() );
            equipmentMapper.updateByPrimaryKeySelective(equipment);
            equipmentId = equipment.getId();
        }else {
            Equipment equipment = new Equipment();
            equipment.setActiveDate(LocalDateTime.now());
            equipment.setStatus(9);
            equipment.setUserId(equitmentVo.getUserId());
            equipment.setMac(equitmentVo.getMac());
            equipment.setGmtCreate(LocalDateTime.now());
            equipmentMapper.insertSelective(equipment);
            equipmentId = equipment.getId();
        }
        //添加群
    EquipmentUserLevelExample example1 = new EquipmentUserLevelExample();
        example1.createCriteria().andUserIdEqualTo(equitmentVo.getUserId()).andEquipmentIdEqualTo(equipmentId);
    List<EquipmentUserLevel> equipmentUserLevels = equipmentUserLevelMapper.selectByExample(example1);
        if (equipmentUserLevels.size()>0){
        log.error("重复添加，跳过");
    }else {
        EquipmentUserLevel equipmentUserLevel = new EquipmentUserLevel();
        equipmentUserLevel.setEquipmentId(equipmentId);
        equipmentUserLevel.setUserId(equitmentVo.getUserId());
        equipmentUserLevel.setLevel(1);
        equipmentUserLevel.setMac(equitmentVo.getMac());
        equipmentUserLevel.setGmtDate(LocalDateTime.now());
        equipmentUserLevelMapper.insertSelective(equipmentUserLevel);
    }
}

    @Override
    public void equitmentUpdateStatus(String mac, Integer status) {
        EquipmentExample example = new EquipmentExample();
        example.createCriteria().andMacEqualTo(mac);
        List<Equipment> equipments = equipmentMapper.selectByExample(example);
        if (equipments.size()>0){
            if(!equipments.get(0).getStatus().equals(status)){
                log.info("更新mac："+mac+"的设备状态为"+status);
                equipments.get(0).setStatus(status);
                equipments.get(0).setGmtModify(LocalDateTime.now());
                equipmentMapper.updateByPrimaryKeySelective(equipments.get(0));
            }
        }
    }

    @Override
    public void equitmentUp(String mac, String upPayload) {

    }

    @Override
    public void update(UpData upData, String mac) {
        EquipmentExample example = new EquipmentExample();
        example.createCriteria().andMacEqualTo(mac);
        List<Equipment> equipments = equipmentMapper.selectByExample(example);
        if (equipments.size()>0){
            Integer id = equipments.get(0).getId();
            EquipmentFuncExample funcExample = new EquipmentFuncExample();
            funcExample.createCriteria().andEquipmentIdEqualTo(id);
            List<EquipmentFunc> equipmentFuncs = equipmentFuncMapper.selectByExample(funcExample);
            if(equipmentFuncs.size()>0){
//                log.info("存在，更新");
                EquipmentFunc func = equipmentFuncs.get(0);
                func.setCabinTemperatureDisplay(upData.getMainTemp());
                func.setThermostatTreatmentTemperatureDisplay(upData.getButtomTemp());
                func.setAmbientTemperatureDisplay(upData.getETemp());
                func.setCabinHumidityDisplay(upData.getHumidity());
                func.setOxygenConcentrationDisplay(upData.getOxygenConcentration());
                func.setCabinTemperatureSetting(upData.getMainTempSetting());
//                func.setCabinTemperatureStatus();
//                func.setCabinTreatmentTemperatureStatus();
                func.setThermostatTreatmentTemperatureSetting(upData.getButtomTempSetting());
//                func.setCabinHumidityStatus();
                func.setCabinHumiditySetting(upData.getHumiditySetting());
                func.setOxygenConcentrationSetting(upData.getOxygenConcentrationSetting());
                func.setCycleState(Integer.parseInt(upData.getCycleState()));
                func.setEmergencyState(Integer.parseInt(upData.getCycleState()));
                func.setNegativeOxygenIonSwitch(Integer.parseInt(upData.getNegativeIonSwitch()));
                func.setUltravioletDisinfectionLampSwitch(Integer.parseInt(upData.getUv()));
                func.setLampSwitch(Integer.parseInt(upData.getFloodlight()));
                func.setMedicalExaminationLampSwitch(Integer.parseInt(upData.getInspectionLamp()));
                if (!StringUtils.isEmpty(upData.getAtomizerTreatmentTime())){
                    func.setAtomizerTreatmentBegin(LocalDateTime.now());
                    func.setAtomizerTreatmentEnd(LocalDateTime.now().plusMinutes(Integer.parseInt(upData.getAtomizerTreatmentTime())));
                    func.setAtomizerTreatmentStatus(31);
                }
                if (!StringUtils.isEmpty(upData.getInfraredPhysiotherapyTime())){
                    func.setInfraredPhysiotherapyBegin(LocalDateTime.now());
                    func.setInfraredPhysiotherapyEnd(LocalDateTime.now().plusMinutes(Integer.parseInt(upData.getInfraredPhysiotherapyTime())));
                    func.setInfraredPhysiotherapyStatus(31);
                }

//                func.setGmtCreate(LocalDateTime.now());
                func.setGmtModify(LocalDateTime.now());
                equipmentFuncMapper.updateByPrimaryKeySelective(func);
            }else {
                log.info("不存在，新增");
                EquipmentFunc func = new EquipmentFunc();
                func.setRegulationMode("manual");//初始化为 手动调节模式
//                func.setCabinTemperatureStatus();
                func.setEquipmentId(id);
                func.setCabinTemperatureDisplay(upData.getMainTemp());
                func.setThermostatTreatmentTemperatureDisplay(upData.getButtomTemp());
                func.setAmbientTemperatureDisplay(upData.getETemp());
                func.setCabinHumidityDisplay(upData.getHumidity());
                func.setOxygenConcentrationDisplay(upData.getOxygenConcentration());
                func.setCabinTemperatureSetting(upData.getMainTempSetting());
//                func.setCabinTemperatureStatus();
//                func.setCabinTreatmentTemperatureStatus();
                func.setThermostatTreatmentTemperatureSetting(upData.getButtomTempSetting());
//                func.setCabinHumidityStatus();
                func.setCabinHumiditySetting(upData.getHumiditySetting());
                func.setOxygenConcentrationSetting(upData.getOxygenConcentrationSetting());
                func.setCycleState(Integer.parseInt(upData.getCycleState()));
                func.setEmergencyState(Integer.parseInt(upData.getCycleState()));
                func.setNegativeOxygenIonSwitch(Integer.parseInt(upData.getNegativeIonSwitch()));
                func.setUltravioletDisinfectionLampSwitch(Integer.parseInt(upData.getUv()));
                func.setLampSwitch(Integer.parseInt(upData.getFloodlight()));
                func.setMedicalExaminationLampSwitch(Integer.parseInt(upData.getInspectionLamp()));
                func.setGmtCreate(LocalDateTime.now());
                func.setGmtModify(LocalDateTime.now());
                if (!StringUtils.isEmpty(upData.getAtomizerTreatmentTime())){
                    func.setAtomizerTreatmentBegin(LocalDateTime.now());
                    func.setAtomizerTreatmentEnd(LocalDateTime.now().plusMinutes(Integer.parseInt(upData.getAtomizerTreatmentTime())));
                    func.setAtomizerTreatmentStatus(31);
                }
                if (!StringUtils.isEmpty(upData.getInfraredPhysiotherapyTime())){
                    func.setInfraredPhysiotherapyBegin(LocalDateTime.now());
                    func.setInfraredPhysiotherapyEnd(LocalDateTime.now().plusMinutes(Integer.parseInt(upData.getInfraredPhysiotherapyTime())));
                    func.setInfraredPhysiotherapyStatus(31);
                }
                equipmentFuncMapper.insertSelective(func);
            }
        }
    }

    @Override
    public void sendEquitment(String mac, String type, String message) {
        try {
            message = "680202"+type+message+"16";
            byte[] bytes = HexUtil.decodeHex(message);
            String s1 = MqttUtils.Bytes2HexString(bytes);
            System.out.println("message:"+s1 );
            mqttPushClient.publish(0,false,mac+"/down",bytes);
            log.info("发送成功");
        } catch (Exception e) {
            log.error("发送失败");
            throw new MqttException("发送给"+mac+"，类型为"+type+",信息为"+message+"失败！");
        }
    }

    @Override
    public List<Equipment> findByUserId(int userid) {
        EquipmentExample example = new EquipmentExample();
        example.createCriteria().andUserIdEqualTo(userid);
        return equipmentMapper.selectByExample(example);
    }

    @Override
    public Equipment findByMac(String mac) {
        EquipmentExample example = new EquipmentExample();
        example.createCriteria().andMacEqualTo(mac);
        return equipmentMapper.selectOneByExample(example);
    }

    @Override
    public EquipmentFunc findByEquipId(int id) {
        EquipmentFuncExample funcExample = new EquipmentFuncExample();
        funcExample.createCriteria().andEquipmentIdEqualTo(id);
        List<EquipmentFunc> equipmentFuncs = equipmentFuncMapper.selectByExample(funcExample);
        if( equipmentFuncs.size() > 0){
            EquipmentFunc equipmentFunc = equipmentFuncs.get(0);
            Equipment equipment = equipmentMapper.selectByPrimaryKey(equipmentFunc.getEquipmentId());
            PresetModelsConditionExample example = new PresetModelsConditionExample();
            example.createCriteria().andEquitmentIdEqualTo(id);
            List<PresetModelsCondition> presetModelsConditions = presetModelsConditionMapper.selectByExample(example);
            equipmentFunc.setHighModes(presetModelsConditions.stream().filter(regulateMode -> regulateMode.getModel().equals(1)).sorted(Comparator.comparing(PresetModelsCondition::getBigger)).collect(Collectors.toList()));
            equipmentFunc.setLowModes(presetModelsConditions.stream().filter(regulateMode -> regulateMode.getModel().equals(2)).sorted(Comparator.comparing(PresetModelsCondition::getLower)).collect(Collectors.toList()));
            //TODO 宠物蓝牙数据发送
            return equipmentFunc;
        }else {
            return null;
        }
    }
    @Override
    public void addRegulateMode(PresetModelsCondition regulateMode) {
        presetModelsConditionMapper.insertSelective(regulateMode);
    }

    @Override
    public void updateRegulateMode(PresetModelsCondition regulateMode) {
        presetModelsConditionMapper.updateByPrimaryKeySelective(regulateMode);
    }

    @Override
    public void deleteRegulateMode(Integer id) {
        presetModelsConditionMapper.deleteByPrimaryKey(id);
    }

    @Override
    public RegulateMode findById(Integer id) {
        return regulateModeMapper.selectByPrimaryKey(id);
    }

    @Override
    public void modelUpdate(String s,String mac) {
        EquipmentExample example = new EquipmentExample();
        example.createCriteria().andMacEqualTo(mac);
        List<Equipment> equipments = equipmentMapper.selectByExample(example);
        if (equipments.size()>0) {
            Integer id = equipments.get(0).getId();
            EquipmentFuncExample funcExample = new EquipmentFuncExample();
            funcExample.createCriteria().andEquipmentIdEqualTo(id);
            List<EquipmentFunc> equipmentFuncs = equipmentFuncMapper.selectByExample(funcExample);
            if (equipmentFuncs.size() > 0) {
                EquipmentFunc equipmentFunc = equipmentFuncs.get(0);
                switch (s){
                    case "manual":
                        equipmentFunc.setRegulationMode("manual");
                        equipmentFunc.setGmtModify(LocalDateTime.now());
                        equipmentFuncMapper.updateByPrimaryKeySelective(equipmentFunc);
                        break;
                    case "preset":
                        equipmentFunc.setRegulationMode("preset");
                        equipmentFunc.setGmtModify(LocalDateTime.now());
                        equipmentFuncMapper.updateByPrimaryKeySelective(equipmentFunc);
                        break;
                    default:
                        throw new BusinessException("不存在该参数");
                }
            }
        }
    }
}
